package org.ucas.faker.web.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ucas.faker.web.dao.patents.*;
import org.ucas.faker.web.utils.model.RawPatent;
import org.ucas.faker.web.dao.*;
import org.ucas.faker.web.entity.patents.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by suemi on 17-7-10.
 */
@Service
@Transactional
public class PatentService {

  @Autowired
  private PatentDao patentDao;

  @Autowired
  private ContentDao contentDao;

  @Autowired
  private MetaDao metaDao;

  @Autowired
  private FeatureDao featureDao;

  @Autowired
  private SymbolDao symbolDao;

  @Autowired
  private AgencyDao agencyDao;

  @Autowired
  private PatentAgencyDao patentAgencyDao;


  @Autowired
  private RecordDao recordDao;

  public Patent load(long id) {
    return patentDao.findOne(id);
  }

  public PatentContent loadContent(long id) {
    return contentDao.findOne(id);
  }

  public PatentMeta loadMeta(long id) {
    return metaDao.findOne(id);
  }

  public PatentMeta loadMeta(PatentMeta.Source source, String sourceId) {
    return metaDao.load(source,sourceId);
  }

  public PatentFeature loadFeature(long id) {
    PatentFeature feature = featureDao.findOne(id);
    if(feature == null) return null;
    List<Symbol> tmp = symbolDao.findByPatentIdAndKind(feature.getId(), Symbol.Category.BRANCH);
    if(tmp != null) feature.setBr(tmp);
    //feature.getId()
    tmp = symbolDao.findByPatentIdAndKind(feature.getId(), Symbol.Category.EFFECT);
    if(tmp != null) feature.setEf(tmp);
    return feature;
  }

  public List<Agency> loadAgencies(long id) {
    return agencyDao.loadByPatentId(id);
  }

  public List<Symbol> loadSymbols(long id) {
    return symbolDao.findByPatentId(id);
  }

  private void persistAgencies(List<Agency> agencies, long patentId) {
    for(Agency agency:agencies) {
      Agency tmp = null;
      if(agency.getWxId() != null) tmp = agencyDao.findByWxIdAndKind(agency.getWxId(),agency.getKind());
      if(tmp != null) agency.setId(tmp.getId());

      agencyDao.save(agency);
    }

    agencyDao.deleteByPatentId(patentId);
    List<PatentAgency> pas = agencies.stream().map(a->{
      return new PatentAgency(patentId,a.getId());
    }).collect(Collectors.toList());
    patentAgencyDao.save(pas);
  }

  private void persistSymbols(List<Symbol> symbols, long patentId) {
    symbolDao.deleteByPatentId(patentId);
    for(Symbol symbol:symbols) symbol.setPatentId(patentId);
    symbolDao.save(symbols);
  }

  public Long create(RawPatent src) {
    System.out.println("1:"+src.getSource());
    System.out.println("2:"+src.getSourceId());
    PatentMeta his = metaDao.load(PatentMeta.Source.of(src.getSource()),src.getSourceId());
    if(his != null) src.id = his.getId();

    PatentMeta meta = new PatentMeta();
    meta.of(src,true);
    if(meta.getCreateAt() == null) {
      meta.setCreateAt(new Date());
      meta.setUpdateAt(new Date());
    }
    
    metaDao.save(meta);
    src.id = meta.getId();

    Patent patent = new Patent();
    patent.of(src,true);
    patent.setId(meta.getId());
    patentDao.save(patent);

    PatentContent content = new PatentContent();
    content.of(src,true);
    content.setId(meta.getId());
    contentDao.save(content);


    persistAgencies(src.agencies(),meta.getId());


    persistSymbols(src.symbols(),meta.getId());

    return meta.getId();
  }

  public void createBatch(List<RawPatent> patents) {
    for(RawPatent patent:patents)
      create(patent);
  }

  public List<PatentWrapper> toGenerate(Long depotId) {
    if(depotId == null) return new ArrayList<>();
    List<Long> ids = metaDao.toGenIds(depotId);
    return ids.stream().map(PatentWrapper::new).collect(Collectors.toList());
  }

  public void persistFeature(PatentFeature feature) {
    featureDao.save(feature);
    System.out.println("\n\n\n\nfeature size:"+feature.getBr().size());
    for(Symbol symbol:feature.getBr()) symbol.setPatentId(feature.getId());
    for(Symbol symbol:feature.getEf()) symbol.setPatentId(feature.getId());

    symbolDao.deleteByPatentIdAndKind(feature.getId(), Symbol.Category.BRANCH);
    symbolDao.deleteByPatentIdAndKind(feature.getId(), Symbol.Category.EFFECT);
    symbolDao.flush();
    symbolDao.save(feature.getBr());
    symbolDao.save(feature.getEf());
    metaDao.setGenerated(feature.getId());
  }

  public List<RawPatent> loadBatch(List<Long> ids) {
    List<RawPatent> res = new ArrayList<>();
    for(Long id:ids) {
      if(id == null) continue;
      PatentWrapper wrapper = new PatentWrapper(id);
      res.add(wrapper.toRaw());
    }
    return res;
  }

}
